package com.adnaan.backend.controller.admin;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.json.JSONObject;
import com.adnaan.backend.common.annotation.RestControllerMapping;
import com.adnaan.backend.common.model.Result;
import com.adnaan.backend.entity.SysUser;
import com.adnaan.backend.entity.vo.LoginVo;
import com.adnaan.backend.service.SysUserService;
import com.adnaan.backend.utils.PasswordUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * author: adnaan
 * create: 2025-01-05 17:28
 * Description:
 */
@RestControllerMapping("/auth")
@Tag(name = "登录管理", description = "登录管理")
@ApiSupport(author = "adnaan", order = 1)
public class LoginController {

    @Resource
    private SysUserService userService;

    @SaIgnore
    @Operation(summary = "账号密码登录")
    @PostMapping("/login")
    public Result<Map<String, String>> login(@RequestBody LoginVo login) {
        SysUser user = userService.getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, login.getUsername()));
        if (user == null) {
            return Result.error("账号或密码错误");
        }
        if (user.getStatus() == 0) {
            return Result.error("账号已被禁用");
        }
        String password = login.getPassword();
        String salt = user.getSalt();
        String decrypt = PasswordUtils.decrypt(user.getPassword(), salt);
        if (password.equals(decrypt)) {
            StpUtil.login(user.getId(), "PC");
            userService.setLastLoginTime(user.getId());
            SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
            Map<String, String> map = new HashMap<>();
            map.put("tokenHead", tokenInfo.getTokenName());
            map.put("token", tokenInfo.getTokenValue());
            map.put("userId", user.getId().toString());
            return Result.success(map);
        }
        return Result.error("账号或密码错误");
    }

    @GetMapping("/logout")
    @Operation(summary = "退出登录")
    public Result<String> logout() {
        StpUtil.logout();
        return Result.success("退出成功");
    }

    @GetMapping("/info")
    @Operation(summary = "获取用户信息")
    public Result<SysUser> info() {
        SysUser user = userService.getById(StpUtil.getLoginIdAsLong());
        user.setRoles(userService.getRoles(user.getId()));
        return Result.success(user);
    }

    @GetMapping("/menu")
    @Operation(summary = "获取用户菜单")
    public Result<List<JSONObject>> menu() {
        SaSession session = StpUtil.getSessionByLoginId(StpUtil.getLoginId());
        List<JSONObject> menus = session.get("menu", () -> userService.listMenuByUserId());
        return Result.success(menus);
    }

    @GetMapping("/permissions")
    @Operation(summary = "获取用户权限")
    public Result<List<String>> permissions() {
        Long loginId = StpUtil.getLoginIdAsLong();
        SaSession session = StpUtil.getSessionByLoginId(loginId);
        List<String> roleList = session.get("Role_List", () -> userService.listRolesByUserId(loginId.toString()));
        List<String> permissions = new ArrayList<>();
        for (String roleCode : roleList) {
            List<String> rolePermissions = session.get("Permission_List", () -> userService.listPermissionsByRoleCode(roleCode));
            // 将每个角色的权限列表添加到总的权限列表中
            permissions.addAll(rolePermissions);
        }
        return Result.success(permissions);
    }

    @GetMapping("/clearCache")
    @Operation(summary = "清除用户缓存")
    public Result<String> clearCache() {
        SaSession session = StpUtil.getSession();
        session.clear();
        return Result.success("清除成功");
    }
}
